﻿using SqlSugar;
using System.Reflection;
using System.Text.Json.Nodes;

namespace BlazorAutoEx.Models
{
    public class Dbcon
    {

        public static string MyDbCon()
        {
            JsonNode root = JsonNode.Parse(File.ReadAllText("appsettings.json"))!;
            //读取appsettings.json里的连接字符串
            return root["ConnectionStrings"]!["DefaultConnection"]!.GetValue<string>();
        }

        public static string MyDbType()
        {
            JsonNode root = JsonNode.Parse(File.ReadAllText("appsettings.json"))!;
            //读取appsettings.json里的数据库类型 
            return root["ConnectionStrings"]!["DbType"]!.GetValue<string>();
        }
        public static DbType SetDBType(string? dbType) //设置数据库类型
        {
            if (Enum.TryParse(dbType, true, out DbType result))
                return result;
            return DbType.SqlServer;
        }

        //多库情况下使用说明：  
        //如果是固定多库可以传 new SqlSugarScope(List<ConnectionConfig>,db=>{}) 文档：多租户  
        //如果是不固定多库 可以看文档Saas分库  
        //用单例模式  
        public static SqlSugarScope db = new(new ConnectionConfig()
        {
            ConnectionString = MyDbCon(),//连接符字串存在appsettings.json里  
            DbType = SetDBType(MyDbType()),//数据库类型  

            IsAutoCloseConnection = true, //不设成true要手动close  
            MoreSettings = new ConnMoreSettings
            {
                // IsCorrectErrorSqlParameterName = true, // 参数名有空格特殊符号使用兼容模式，对性能会有影响，能局部修改配置就局部，尽量不要全局使用  
            },
            ConfigureExternalServices =
                    {
                        //注意:  这儿AOP设置不能少
                        EntityService = (c, p) =>
                        {
                            /***高版C#写法***/
                            //支持string?和string  
                            if (p.IsPrimarykey == false && new NullabilityInfoContext()
                             .Create(c).WriteState is NullabilityState.Nullable)
                            {
                                p.IsNullable = true;
                            }

                        },

                        SqlFuncServices = [
                            new()
                            {  
                                //建一个NullIf的SQL函数  
                                UniqueMethodName = "NullIf",
                                MethodValue = (expInfo, dbType, expContext) =>
                                {
                                    if(dbType==DbType.SqlServer)
                                        return string.Format("NULLIF({0}, {1})", expInfo.Args[0].MemberName, expInfo.Args[1].MemberName);
                                    else
                                        throw new Exception("未实现");
                                }
                            }
                        ]
                    }
        },
            db =>
            {
                ////(A)全局生效配置点，一般AOP和程序启动的配置扔这里面 ，所有上下文生效
                ////调试SQL事件，可以删掉
                //db.Aop.OnLogExecuting = (sql, pars) =>
                //{

                //    //获取原生SQL推荐 5.1.4.63  性能OK
                //    Console.WriteLine(UtilMethods.GetNativeSql(sql, pars));

                //    //获取无参数化SQL 对性能有影响，特别大的SQL参数多的，调试使用
                //    //Console.WriteLine(UtilMethods.GetSqlString(DbType.SqlServer,sql,pars))
                //};

                ////多个配置就写下面
                ////db.Ado.IsDisableMasterSlaveSeparation=true;

                ////注意多租户 有几个设置几个
                ////db.GetConnection(i).Aop
            });

        public static T? NullIf<T>(T a, T b) where T : struct
        {
            throw null!;
        }

    }


    //测试用-定时写入数据库
    public class TimedSerText
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int ID { get; set; }
        public DateTime? RunTime { get; set; }

    }

    // 定时服务配置数据库表
    public class TimedSerCfgdb
    {
        [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        public string Name { get; set; }
        public string? DbCon { get; set; }
        public int? SetDay { get; set; }
        public int? SetHour { get; set; }
        public int? SetMinute { get; set; }
        public int? ExecuteSet { get; set; }

        [SugarColumn(IsIgnore = true)]
        public int ExeHour
        {
            get => ExeTimeOnly.Hours;
            set => ExeTimeOnly = new(value, ExeTimeOnly.Minutes, ExeTimeOnly.Seconds);
        }
        [SugarColumn(IsIgnore = true)]
        public int ExeMinute
        {
            get => ExeTimeOnly.Minutes;
            set => ExeTimeOnly = new(ExeTimeOnly.Hours, value, ExeTimeOnly.Seconds);
        }
        [SugarColumn(IsIgnore = true)]
        public int ExeSecond
        {
            get => ExeTimeOnly.Seconds;
            set => ExeTimeOnly = new(ExeTimeOnly.Hours, ExeTimeOnly.Minutes, value);
        }
        [SugarColumn(IsIgnore = true)]
        public TimeSpan ExeTimeOnly { get; set; }
        public long ExeTime
        {
            get => ExeTimeOnly.Ticks;
            set => ExeTimeOnly = new(value);
        }
        public DateTime? EveryDayTime { get; set; }
        public bool Effective { get; set; }    //有效的
        public bool IsRunning { get; set; }    //运行
        public double? ExTimeSec { get; set; }  //下次运行间隔时间秒
        public DateTime? NextTime { get; set; } //下次运行时间
        public DateTime? LastTime { get; set; } //上次运行时间

    }

    // 定时服务-每天执行时间
    public class TimeAutoSet
    {

        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        [SugarColumn(IsIgnore = true)]
        public TimeOnly ExeTimeOnly { get; set; }
        public long ExeTime
        {
            get => ExeTimeOnly.Ticks;
            set => ExeTimeOnly = new(value);
        }
    }

}
